package com.concurrent.synchronizeandreentrant;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: MySynchronized
 * @Description:  同步代码块
 * @author: li
 * @Date: 2021/8/18 3:26 下午
 */
public class MySynchronized {
    int sum = 0;
    int sub = 100;
    static int sumStatic = 0;
    public MySynchronized(int sum, int sub) {
        this.sum = sum;
        this.sub = sub;
    }

    public void add(){

        for (int i = 0; i < 10; i++) {
            // 同步代码块
            /**
             *  它只作用于同一个对象，如果调用两个对象上的同步代码块，就不会进行同步
             */
            synchronized (this){
                sum+=1;
            }
            System.out.println(sum+"\n");
        }

    }

    public synchronized void sub(){
        //同步方法
        /**
         * 它和同步代码块一样，作用于同一个对象。
         */
        for (int i = 0; i < 10; i++) {
            sub--;
            System.out.println(sub+"\n");
        }
    }

    public void func(){
        /**
         * 作用于整个类，也就是说两个线程调用同一个类的不同对象上的这种同步语句，也会进行同步。
         */
        synchronized (MySynchronized.class){
            for (int i = 0; i < 10; i++) {
                sum++;
                System.out.println(sum+"\n");
            }
        }
    }

    public static synchronized void func1(){
        /**
         * 同步一个静态方法,作用于整个类
         */
        for (int i = 0; i < 10; i++) {
            sumStatic++;
            System.out.println(sumStatic);
        }

    }

    public static void main(String[] args) {
        //核心线程数
        int corePoolSize = 3;
        //最大线程数
        int maxPoolSize = 6;
        //非核心线程，闲置存活时间
        long keepAliveTime = 2;
        //时间单位，秒
        TimeUnit timeUnit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(2);

        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, timeUnit, queue, new ThreadPoolExecutor.AbortPolicy());
        MySynchronized mySynchronized = new MySynchronized(0,100);
        MySynchronized mySynchronized1 = new MySynchronized(0,100);
        for (int i = 0; i < 6; i++) {
            if (i%2 == 0){
                threadPoolExecutor.submit(() -> {
                    // 测试区
                    mySynchronized.add();
                });
            }else {
                threadPoolExecutor.submit(() -> {
                    mySynchronized1.add();
                });
            }

        }
        threadPoolExecutor.shutdown();
    }
}
